package com.codedancer.campus.client.api.user;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.codedancer.campus.client.api.user.ro.*;
import com.codedancer.campus.client.service.IUserService;
import com.codedancer.campus.client.service.bo.user.*;
import com.codedancer.campus.client.service.vo.user.UserFanVo;
import com.codedancer.campus.client.service.vo.user.UserFollowVo;
import com.codedancer.campus.client.service.vo.user.UserInfoVo;
import com.codedancer.campus.common.anno.Limit;
import com.codedancer.campus.common.anno.PassToken;
import com.codedancer.campus.common.core.BaseApi;
import com.codedancer.campus.common.response.ApiResponse;
import com.qq.connect.QQConnectException;
import com.qq.connect.oauth.Oauth;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api/user")
@CrossOrigin(methods = {RequestMethod.GET, RequestMethod.POST, RequestMethod.DELETE,
    RequestMethod.PUT}, maxAge = 3600)
@Api(value = "用户Api", description = "用户Api", tags = "用户Api")
public class UserApi extends BaseApi {

    @Autowired
    private IUserService userService;

    @PostMapping("/login/phone")
    @ApiOperation("用户手机号登录")
    @PassToken
    @Limit(key = "LOGIN_PHONE", permitsPerSecond = 3, timeout = 1000, msg = "系统繁忙，请稍后再试！")
    public ApiResponse<String> loginByPhone(
        @RequestBody @Valid @ApiParam(value = "登录Ro", required = true)
        UserLoginRo userLoginRo) throws UnsupportedEncodingException, NoSuchAlgorithmException {
        UserLoginBo userLoginBo = BeanUtil.copyProperties(userLoginRo, UserLoginBo.class);
        return success(userService.loginByPhone(userLoginBo));
    }

    @GetMapping("/current-user-info")
    @ApiOperation("获取当前用户信息")
    public ApiResponse<UserInfoVo> currentUserInfo() {
        return success(userService.currentUserInfo(currentLoginUuid()));
    }

    @PutMapping("/update-avatar")
    @ApiOperation("修改头像")
    public ApiResponse<Void> updateAvatar(
        @RequestBody @Valid @ApiParam(value = "修改头像Ro", required = true)
        UserUpdateAvatarRo userUpdateAvatarRo) {
        UserUpdateAvatarBo userUpdateAvatarBo = BeanUtil.copyProperties(userUpdateAvatarRo,
            UserUpdateAvatarBo.class);
        userUpdateAvatarBo.setCurrentUserUuid(currentLoginUuid());
        userService.updateAvatar(userUpdateAvatarBo);
        return success();
    }

    @PutMapping("/set-basic-message")
    @ApiOperation("设置基本信息")
    public ApiResponse<Void> setBasicMessage(
        @RequestBody @Valid @ApiParam(value = "用户设置信息Ro", required = true)
        SetBasicMessageRo setBasicMessageRo) {
        SetBasicMessageBo setBasicMessageBo = BeanUtil.copyProperties(setBasicMessageRo,
            SetBasicMessageBo.class);
        setBasicMessageBo.setCurrentUserUuid(currentLoginUuid());
        userService.setBasicMessage(setBasicMessageBo);
        return success();
    }

    @PutMapping("/update-user-info")
    @ApiOperation("修改用户信息")
    public ApiResponse<Void> updateUserInfo(
        @RequestBody @Valid @ApiParam(value = "用户修改信息Ro", required = true)
        UserUpdateInfoRo userUpdateInfoRo) {
        UserUpdateInfoBo userUpdateInfoBo = BeanUtil.copyProperties(userUpdateInfoRo,
            UserUpdateInfoBo.class);
        userUpdateInfoBo.setCurrentUserUuid(currentLoginUuid());
        userService.updateUserInfo(userUpdateInfoBo);
        return success();
    }

    @GetMapping("/get/{userUuid}")
    @ApiOperation("根据用户uuid获取用户信息")
    public ApiResponse<UserInfoVo> getByUserUuid(
        @PathVariable(value = "userUuid", required = true) @ApiParam(value = "用户uuid", required = true) String userUuid) {
        return success(userService.getByUserUuid(userUuid));
    }

    @GetMapping("/login/pull-up-qq")
    @ApiOperation("QQ页面登录拉起")
    @PassToken
    public void pullUpQQ(HttpServletRequest request, HttpServletResponse response) {
        response.setContentType("text/html;charset=utf-8");
        try {
            response.sendRedirect(new Oauth().getAuthorizeURL(request));
        } catch (QQConnectException | IOException e) {
            e.printStackTrace();
        }
    }

    @GetMapping("/login/qq")
    @ApiOperation("QQ回调登录")
    @PassToken
    public void loginByQQ(HttpServletRequest request, HttpServletResponse response)
        throws IOException, NoSuchAlgorithmException, QQConnectException {
        userService.loginByQQ(request, response);
    }

    @PostMapping("/update-password")
    @ApiOperation("修改密码(返回token)")
    public ApiResponse<String> updatePassword(
        @RequestBody @Valid @ApiParam(value = "修改密码Ro", required = true)
        UpdatePasswordRo updatePasswordRo)
        throws UnsupportedEncodingException, NoSuchAlgorithmException {
        UpdatePasswordBo updatePasswordBo = BeanUtil
            .copyProperties(updatePasswordRo, UpdatePasswordBo.class);
        updatePasswordBo.setCurrentUserUuid(currentLoginUuid());
        return success(userService.updatePassword(updatePasswordBo));
    }

    @PostMapping("/follow/{uuid}")
    @ApiOperation("关注用户")
    public ApiResponse<Void> follow(
        @PathVariable(value = "uuid", required = true) @ApiParam(value = "用户uuid", required = true) String uuid) {
        userService.follow(uuid, currentLoginUuid());
        return success();
    }

    @PutMapping("/cancel-follow/{uuid}")
    @ApiOperation("取消关注用户")
    public ApiResponse<Void> cancelFollow(
        @PathVariable(value = "uuid", required = true) @ApiParam(value = "用户uuid", required = true) String uuid) {
        userService.cancelFollow(uuid, currentLoginUuid());
        return success();
    }

    @GetMapping("/is-follow/{uuid}")
    @ApiOperation("是否关注")
    public ApiResponse<Boolean> isFollow(
        @PathVariable(value = "uuid", required = true) @ApiParam(value = "用户uuid", required = true) String uuid) {
        return success(userService.isFollow(uuid, currentLoginUuid()));
    }

    @GetMapping("/page/follow")
    @ApiOperation("分页查询关注用户")
    public ApiResponse<IPage<UserFollowVo>> pageFollow(
        @ApiParam(value = "关注用户分页查询Ro", required = false)
        UserFollowPageSearchRo userFollowPageSearchRo) {
        UserFollowPageSearchBo userFollowPageSearchBo = BeanUtil
            .copyProperties(userFollowPageSearchRo, UserFollowPageSearchBo.class);
        userFollowPageSearchBo.setCurrentUserUuid(currentLoginUuid());
        return success(userService.pageFollow(userFollowPageSearchBo));
    }

    @PutMapping("/update/background-image")
    @ApiOperation("修改背景图")
    public ApiResponse<Void> updateBackgroundImage(
        @RequestBody @Valid @ApiParam(value = "修改背景图Ro", required = true)
        UserUpdateBackgroundImageRo userUpdateBackgroundImageRo) {
        UserUpdateBackgroundImageBo userUpdateBackgroundImageBo = BeanUtil
            .copyProperties(userUpdateBackgroundImageRo, UserUpdateBackgroundImageBo.class);
        userUpdateBackgroundImageBo.setCurrentUserUuid(currentLoginUuid());
        userService.updateBackgroundImage(userUpdateBackgroundImageBo);
        return success();
    }

    @PutMapping("/update-phone")
    @ApiOperation("修改手机号")
    public ApiResponse<Void> updatePhone(
        @RequestBody @Valid @ApiParam(value = "修改手机号Ro", required = true)
        UpdatePhoneRo updatePhoneRo) {
        UpdatePhoneBo updatePhoneBo = BeanUtil.copyProperties(updatePhoneRo, UpdatePhoneBo.class);
        updatePhoneBo.setCurrentUserUuid(currentLoginUuid());
        userService.updatePhone(updatePhoneBo);
        return success();
    }

    @PostMapping("/login/password")
    @ApiOperation("密码登录")
    @PassToken
    public ApiResponse<String> loginByPassword(
        @RequestBody @Valid @ApiParam(value = "用户密码登录Ro", required = true)
        UserLoginPasswordRo userLoginPasswordRo)
        throws UnsupportedEncodingException, NoSuchAlgorithmException {
        UserLoginBo userLoginBo = BeanUtil.copyProperties(userLoginPasswordRo, UserLoginBo.class);
        return success(userService.loginByPassword(userLoginBo));
    }

    @PostMapping("/register-email")
    @ApiOperation("邮箱注册")
    @PassToken
    public ApiResponse<String> registerEmail(@RequestBody @Valid @ApiParam(value = "用户邮箱注册Ro", readOnly = true) UserEmailRegisterRo userEmailRegisterRo) throws UnsupportedEncodingException, NoSuchAlgorithmException {
        UserEmailRegisterBo userEmailRegisterBo = BeanUtil.copyProperties(userEmailRegisterRo, UserEmailRegisterBo.class);
        return success(userService.registerEmail(userEmailRegisterBo));
    }

    @PostMapping("/manual-register")
    @ApiOperation("手动注册")
    @PassToken
    @Limit(key = "MANUAL_REGISTER", permitsPerSecond = 5, timeout = 1000, msg = "系统繁忙，请稍后再试！")
    public ApiResponse<String> manualRegister(@RequestBody @Valid @ApiParam(value = "用户手动注册Ro", required = true) UserManualRegisterRo userManualRegisterRo) throws UnsupportedEncodingException, NoSuchAlgorithmException {
        UserManualRegisterBo userManualRegisterBo = BeanUtil.copyProperties(userManualRegisterRo, UserManualRegisterBo.class);
        return success(userService.manualRegister(userManualRegisterBo));
    }

    @GetMapping("/page/fan")
    @ApiOperation("分页查询关注粉丝(关注我的人)")
    public ApiResponse<IPage<UserFanVo>> pageFan(
        @ApiParam(value = "粉丝分页查询Ro", required = false)
        UserFanPageSearchRo userFanPageSearchRo) {
        UserFanPageSearchBo userFanPageSearchBo = BeanUtil
            .copyProperties(userFanPageSearchRo, UserFanPageSearchBo.class);
        userFanPageSearchBo.setCurrentUserUuid(currentLoginUuid());
        return success(userService.pageFan(userFanPageSearchBo));
    }
}
